package com.zg.assistant.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.zg.assistant.enm.DirectionEnum;
import com.zg.assistant.service.CommunicationService;
import com.zg.common.core.constant.AssistantContants;
import com.zg.common.core.dao.assistant.entity.WebSocketMessage;
import com.zg.common.core.dao.assistant.mapper.WebSocketMessageMapper;
import com.zg.common.web.socket.WebSocketServer;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Map;

/**
 * 通信服务实现类
 * @author zg
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class CommunicationServiceImpl implements CommunicationService {

    private final WebSocketMessageMapper webSocketMessageMapper;
    private final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 发送WebSocket消息
     * @param content 消息内容
     * @param userName 用户名
     * @return 发送结果
     */
    @Override
    public boolean sendWebSocketMessage(String content, String uuid, String userName) {
        try {
            // 截取第一个冒号前的内容
            String directionStr = content.substring(0, content.indexOf(":"));
            DirectionEnum direction = DirectionEnum.valueOf(directionStr.toUpperCase());
            // 截取第一个冒号后的内容
            content = content.substring(content.indexOf(":") + 1);

            boolean sendResult = false;

            String clientIdSuffix = uuid + "-" + userName;
            // 根据消息方向处理发送逻辑
            switch (direction.getDirection()) {
                case AssistantContants.DIRECTION_TO_PC:
                    sendResult = sendToTargetClient(AssistantContants.CLIENT_TYPE_PC + clientIdSuffix, content, userName);
                    break;
                case AssistantContants.DIRECTION_TO_APP:
                    sendResult = sendToTargetClient(AssistantContants.CLIENT_TYPE_APP + clientIdSuffix, content, userName);
                    break;
                case AssistantContants.DIRECTION_TO_ALL:
                    sendResult = sendToAllClients(content, userName, clientIdSuffix);
                    break;
                default:
                    log.warn("无效的消息方向: {}", direction);
                    return false;
            }

            WebSocketMessage webSocketMessage = createWebSocketMessage(direction, content, userName);
            if (sendResult) {
                webSocketMessage.setSendStatus(AssistantContants.SEND_STATUS_SUCCESS);
                log.info("消息发送成功并保存到数据库 - 用户ID: {}, 方向: {}", userName, direction.getDirection());
            } else {
                webSocketMessage.setSendStatus(AssistantContants.SEND_STATUS_FAIL);
                log.info("消息发送失败并保存到数据库 - 用户ID: {}, 方向: {}", userName, direction.getDirection());
            }
            saveWebSocketMessage(webSocketMessage);

            return sendResult;
        } catch (Exception e) {
            log.error("消息处理失败", e);
            return false;
        }
    }

    /**
     * 发送WebSocket JSON格式消息
     * @param params 消息参数
     * @return 发送结果
     */
    @Override
    public boolean sendWebSocketJsonMessage(Map<String, Object> params) {
        try {
            // 提取必要参数
            String channelId = params.get("channelId").toString();
            String showClient = params.get("showClient").toString();

            // 将Map直接转换为JSON字符串
            String jsonContent = objectMapper.writeValueAsString(params);
            jsonContent = "sendOrder:" + jsonContent;

            // 根据客户端类型构建发送ID
            String sendClientId = null;
            String direction = null;

            if (AssistantContants.SHOW_CLIENT_PC.equals(showClient)) {
                sendClientId = AssistantContants.CLIENT_TYPE_PC + channelId;
                direction = AssistantContants.DIRECTION_TO_PC;
            } else if (AssistantContants.SHOW_CLIENT_APP.equals(showClient)) {
                sendClientId = AssistantContants.CLIENT_TYPE_APP + channelId;
                direction = AssistantContants.DIRECTION_TO_APP;
            } else {
                log.warn("无效的客户端类型: {}", showClient);
                return false;
            }

            // 检查客户端连接状态并发送消息
            if (WebSocketServer.isClientConnected(sendClientId)) {
                WebSocketServer.sendMsg(sendClientId, jsonContent);

                // 记录消息发送日志
                log.info("JSON消息发送成功 - 通道ID: {}, 指令: {}, 客户端类型: {}",
                        channelId, params.get("order"), showClient);

                // 保存消息记录
                WebSocketMessage message = new WebSocketMessage();
                message.setContent(jsonContent);
                message.setSendTime(LocalDateTime.now());
                message.setSendStatus(AssistantContants.SEND_STATUS_SUCCESS);
                message.setDirection(direction);
                saveWebSocketMessage(message);

                return true;
            } else {
                // 保存失败消息记录
                WebSocketMessage message = new WebSocketMessage();
                message.setContent(jsonContent);
                message.setSendTime(LocalDateTime.now());
                message.setSendStatus(AssistantContants.SEND_STATUS_FAIL);
                message.setDirection(direction);
                saveWebSocketMessage(message);

                log.warn("JSON消息发送失败，通道不在线 - 通道ID: {}, 客户端类型: {}",
                        channelId, showClient);
                return false;
            }
        } catch (Exception e) {
            log.error("发送JSON消息失败", e);
            return false;
        }
    }

    /**
     * 创建WebSocket消息对象
     */
    private WebSocketMessage createWebSocketMessage(DirectionEnum direction, String content, String userName) {
        WebSocketMessage webSocketMessage = new WebSocketMessage();
        webSocketMessage.setUserName(userName);
        webSocketMessage.setContent(content);
        webSocketMessage.setDirection(direction.getDirection());
        webSocketMessage.setSendTime(LocalDateTime.now());
        return webSocketMessage;
    }

    /**
     * 保存WebSocket消息到数据库
     */
    private void saveWebSocketMessage(WebSocketMessage webSocketMessage) {
        try {
            webSocketMessage.setSendTime(LocalDateTime.now());
            webSocketMessageMapper.insert(webSocketMessage);
        } catch (Exception e) {
            log.error("保存WebSocket消息到数据库失败", e);
        }
    }

    /**
     * 发送消息到指定客户端
     */
    private boolean sendToTargetClient(String targetClientId, String message, String userName) {
        if (!WebSocketServer.isClientConnected(targetClientId)) {
            log.warn("消息发送失败，目标客户端不在线 - 用户ID: {}, 目标: {}", userName, targetClientId);
            return false;
        }

        try {
            WebSocketServer.sendMsg(targetClientId, message);
            log.info("消息发送成功 - 用户ID: {}, 目标: {}", userName, targetClientId);
            return true;
        } catch (Exception e) {
            log.error("发送WebSocket消息失败 - 用户ID: {}, 目标: {}", userName, targetClientId, e);
            return false;
        }
    }

    /**
     * 发送消息到所有客户端
     */
    private boolean sendToAllClients(String message, String userName, String clientIdSuffix) {
        String pcClientId = AssistantContants.CLIENT_TYPE_PC + clientIdSuffix;
        String appClientId = AssistantContants.CLIENT_TYPE_APP + clientIdSuffix;
        // 检查PC端连接状态
        if (!WebSocketServer.isClientConnected(pcClientId)) {
            log.warn("消息发送失败，PC端客户端不在线 - 用户ID: {}, 目标: {}", userName, pcClientId);
            return false;
        }

        // 检查移动端连接状态
        if (!WebSocketServer.isClientConnected(appClientId)) {
            log.warn("消息发送失败，移动端客户端不在线 - 用户ID: {}, 目标: {}", userName, appClientId);
            return false;
        }

        try {
            // 发送到PC端
            WebSocketServer.sendMsg(pcClientId, message);
            // 发送到移动端
            WebSocketServer.sendMsg(appClientId, message);
            log.info("消息发送成功 - 用户ID: {}, 目标: PC端和移动端", userName);
            return true;
        } catch (Exception e) {
            log.error("发送WebSocket消息失败 - 用户ID: {}, 目标: PC端和移动端", userName, e);
            return false;
        }
    }
}
